package com.beiding.jsonanalyzer.querylink;

import com.beiding.jsonanalyzer.analyze.KeyMode;
import com.beiding.jsonanalyzer.analyze.Orderer;
import com.beiding.jsonanalyzer.flow.ValueNode;
import com.beiding.jsonanalyzer.flow.BranchNode;
import com.beiding.jsonanalyzer.flow.flowevents.*;

import java.util.*;

public class OrderQueryLinkNode<W extends ValueNode> extends ComputeNode<W> {

    private Orderer orderer = new Orderer();

    public OrderQueryLinkNode(QueryLinkNode<W> preNode, KeyMode keyMode) {
        super(preNode);
        orderer.keyMode(keyMode);
    }

    public OrderQueryLinkNode<W> asc(Object key) {
        orderer.by(key, Orderer.OrderEnum.ASC);
        return this;
    }

    public OrderQueryLinkNode<W> desc(Object key) {
        orderer.by(key, Orderer.OrderEnum.DESC);
        return this;
    }


    public OrderQueryLinkNode<W> custom(Object key, Comparator<Object> sortFunc) {
        orderer.by(key, sortFunc);
        return this;
    }


    @Override
    protected void bindByComputeNode(BranchNode<W> preResult, BranchNode<W> newBranchNode) {

        List<W>[] o = new List[]{new ArrayList()};

        ComputeNodeUtils.bindBaseEvent(preResult, newBranchNode);

        //批开始
        preResult.onDataEvent(BatchStartEvent.eventType(), newBranchNode::signDataEvent);

        //批结束
        preResult.onDataEvent(BatchEndEvent.eventType(), event -> {

            List<W> ws = orderer.orderFor(o[0]);
            for (W w : ws) {
                newBranchNode.signDataEvent(new DataNodeEvent<>(w));
            }

            newBranchNode.signDataEvent(event);
            o[0] = new ArrayList<>();

        });

        preResult.onDataEvent(DataNodeEvent.eventType(), event -> {
            o[0].add(event.getData());
        });
    }
}
